﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.Linq;
using System.Text;

namespace WHLRDF
{
    /// <summary>
    /// 访问静态页面过滤器
    /// </summary>
    [System.AttributeUsage(AttributeTargets.Method)]
    public class StaticHtmlAttribute:ActionFilterAttribute
    {
        /// <summary>
        /// 静态路由配置
        /// </summary>
        /// <param name="url">静态路由地址</param>
        /// <param name="idfield">数据id名称</param>
        public StaticHtmlAttribute(string url,string idfield="id")
        {
            Url = url;
            idField = idfield;
        }
        public string Url { get; set; }

        public string idField { get; set; }

        /// <summary>
        /// 是否是功能页面
        /// </summary>
        public bool IsPage = true;
        /// <summary>
        /// 是否清除文件标识
        /// </summary>
        private string RemoveClearKey = "remove";

        /// <summary>
        /// get 是否访问html 默认true
        /// </summary>
        public bool IsGet = true;
        /// <summary>
        /// post 是否访问html默认false
        /// </summary>
        public bool IsPost = false;
        /// <summary>
        /// 静态文件根目录
        /// </summary>
        private string StaticFilesRootName
        {
            get
            {
                return ApplicationEnvironments.Site.ConfigPath.Where(x=>x.RootKey==ConfigPathKeyType.statichtml).FirstOrDefault().Path+"/" ;
            }
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if ((AppHttpContext.IsPost && IsPost)||(!AppHttpContext.IsPost && IsGet))
            {
                string id = context.RouteData.Values.ContainsKey(idField) ? context.RouteData.Values[idField].ToString() : "";
                if (string.IsNullOrEmpty(id) && context.HttpContext.Request.Query.ContainsKey(idField))
                {
                    id = context.HttpContext.Request.Query[idField];
                }
                if (string.IsNullOrWhiteSpace(Url))
                {
                    //获取请求的区域，控制器，action名称
                    string areaName = context.RouteData.Values["area"]?.ToString();
                    string controllerName = context.RouteData.Values["controller"]?.ToString();
                    string actionName = context.RouteData.Values["action"]?.ToString();
                    if (!string.IsNullOrWhiteSpace(areaName))
                    {
                        Url += areaName + "/";
                    }
                    if (!string.IsNullOrWhiteSpace(controllerName))
                    {
                        Url += controllerName + "/";
                    }
                    if (!string.IsNullOrWhiteSpace(actionName))
                    {
                        Url += actionName;
                    }
                }
                string filePath = StaticFilesRootName + string.Format(Url, id);
                FileInfo info = new FileInfo(filePath);

                //判断文件是否存在
                if (info.Exists)
                {
                    //如果存在，直接读取文件
                    using (FileStream fs = File.Open(filePath, FileMode.Open))
                    {
                        using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
                        {
                            //通过contentresult返回文件内容
                            ContentResult contentresult = new ContentResult();
                            contentresult.Content = sr.ReadToEnd();
                            contentresult.ContentType = "text/html";
                            context.Result = contentresult;
                        }
                    }
                    if (!IsPage) //非功能静态页面
                    {
                        var tNum = DateTime.Compare(info.CreationTime.AddMinutes(30), DateTime.Now);
                        if (context.HttpContext.Request.Query.ContainsKey(RemoveClearKey) || tNum < 0)
                        {
                            RemoveClearKey = context.HttpContext.Request.Query[RemoveClearKey];
                            if (!string.IsNullOrWhiteSpace(RemoveClearKey))
                            {
                                File.Delete(filePath);
                            }
                        }
                    }

                }
            }
           
            base.OnActionExecuting(context);


        }
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            if ((AppHttpContext.IsPost && IsPost) || (!AppHttpContext.IsPost && IsGet))
            {
                CreateHtml(context);
            }
            base.OnActionExecuted(context);
        }

        private void CreateHtml(ActionExecutedContext context)
        {
            IActionResult actionResult = context.Result;
            if (actionResult is ViewResult)
            {
                ViewResult viewResult = actionResult as ViewResult;
                //下面的代码就是执行这个ViewResult，并把结果的html内容放到一个StringBuiler对象中
                var services = context.HttpContext.RequestServices;
                var option = services.GetRequiredService<IOptions<MvcViewOptions>>();
                var executor = services.GetRequiredService<IActionResultExecutor<ViewResult>>() as ViewResultExecutor
    ?? throw new ArgumentNullException("executor");
                var result = executor.FindView(context, viewResult);
                result.EnsureSuccessful(originalLocations: null);
                var view = result.View;
                StringBuilder builder = new StringBuilder();

                using (var writer = new StringWriter(builder))
                {
                    var viewContext = new ViewContext(
                    context,
                    view,
                    viewResult.ViewData,
                    viewResult.TempData,
                    writer,
                    option.Value.HtmlHelperOptions);

                    view.RenderAsync(viewContext).GetAwaiter().GetResult();
                    //这句一定要调用，否则内容就会是空的
                    writer.Flush();
                }
                //按照规则生成静态文件名称

                string id = context.RouteData.Values.ContainsKey(idField) ? context.RouteData.Values[idField].ToString() : "";
                if (string.IsNullOrEmpty(id) && context.HttpContext.Request.Query.ContainsKey(idField))
                {
                    id = context.HttpContext.Request.Query[idField];
                }
                string filePath = StaticFilesRootName + string.Format(Url, id);
                FileInfo info = new FileInfo(filePath);
                if (!info.Exists)
                {
                    if (!info.Directory.Exists)
                    {
                        info.Directory.Create();
                    }
                }

                //写入文件
                using (FileStream fs = File.Open(filePath, FileMode.Create))
                {
                    using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
                    {
                        sw.Write(builder.ToString());
                    }
                }
                //输出当前的结果
                ContentResult contentresult = new ContentResult();
                contentresult.Content = builder.ToString();
                contentresult.ContentType = "text/html";
                context.Result = contentresult;
            }
        }
        
    }
}
